home *** CD-ROM | disk | FTP | other *** search
- /*======================================================================
- *
- * FILE:
- * stubinout.c
- *
- * IDENTIFICATION:
- * $Header: /private/postgres/src/rules/stubs/RCS/stubinout.c,v 1.9 1991/02/24 00:47:39 cimarron Exp $
- *
- * DESCRIPTION
- *
- * This file contains the routines that transform a stub
- * record to a string and vice versa.
- * If the stub record is in the 'Prs2Stub' format use the routines
- * 'prs2StubToString' and 'prs2StringToStub'. If they are in the
- * 'Prs2RawStub' format, usre 'stubin' and 'stubout'
- *
- *
- *======================================================================
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include "rules/prs2.h"
- #include "rules/prs2stub.h"
- #include "parser/parse.h" /* for the AND, NOT, OR */
- #include "utils/log.h"
- #include "tmp/datum.h"
- #include "nodes/primnodes.h"
- #include "nodes/primnodes.a.h"
-
- extern Const RMakeConst();
- extern Param RMakeParam();
- extern LispValue StringToPlan();
-
- /*-------------------
- * these routines are local to this file.
- */
- static char *appendString();
- static void skipToken();
- static long readLongInt();
- static char readChar();
- static Name readName();
-
- #define ISBLANK(c) ((c)==' ' || (c)=='\t' || (c)=='\n')
-
-
- /*--------------------------------------------------------------------
- *
- * stubout
- *
- * Given a "Prs2RawStub" transform it to a string readable by humans
- *
- *--------------------------------------------------------------------
- */
- char *
- stubout(rawStub)
- Prs2RawStub rawStub;
- {
- Prs2Stub relstub;
- char *res;
-
- relstub = prs2RawStubToStub(rawStub);
- res = prs2StubToString(relstub);
- prs2FreeStub(relstub, true);
- return(res);
- }
-
- /*--------------------------------------------------------------------
- *
- * stubin
- *
- * Given a string rerpresentin a rule stub record, recreate
- * the 'Prs2RawStub' struct.
- *
- *--------------------------------------------------------------------
- */
- Prs2RawStub
- stubin(s)
- char *s;
- {
- Prs2Stub relstub;
- Prs2RawStub rawStub;
-
- relstub = prs2StringToStub(s);
- rawStub = prs2StubToRawStub(relstub);
- prs2FreeStub(relstub, true);
- return(rawStub);
- }
-
- /*--------------------------------------------------------------------
- *
- * prs2StubToString
- *
- * Given a stub record create a string containing a represeantation
- * suitable for printing
- *
- * NOTE: space is allocated for the string. When you don't need it
- * anymore, use 'pfree()'
- *--------------------------------------------------------------------
- */
- char *
- prs2StubToString(relstub)
- Prs2Stub relstub;
- {
-
- char *res;
- char s1[200];
- char *s2;
- int i,j, k;
- int maxLength;
- Prs2OneStub oneStub;
- char *p;
- Size size;
- int l;
-
- /*
- * initialize res to the null string.
- */
- maxLength = 0;
- res = NULL;
-
- /*
- * print the number of stubs...
- */
- sprintf(s1, "(numOfStubs: %d", relstub->numOfStubs);
- res = appendString(res, s1, &maxLength);
-
- for (i=0; i<relstub->numOfStubs; i++) {
- /*
- * print the information for this stub record
- */
- oneStub = relstub->stubRecords[i];
- sprintf(s1, " (ruleId: %ld stubId: %u count: %d lock: ",
- oneStub->ruleId,
- oneStub->stubId,
- oneStub->counter);
- res = appendString(res, s1, &maxLength);
- /*
- * now print the rule lock
- * Enclose it in double quotes, so that it
- * will be easy for `prs2StringToStub' to read it
- */
- s2 = RuleLockToString(oneStub->lock);
- res = appendString(res, "`", &maxLength);
- res = appendString(res, s2, &maxLength);
- res = appendString(res, "' ", &maxLength);
- pfree(s2);
- /*
- * Now print the qualification...
- * NOTE: in order to be able to easily read this
- * qual back (by prs2StringToStub) we
- * enclose it in quotes.
- */
- res = appendString(res, "qual: ", &maxLength);
- s2 = lispOut(oneStub->qualification);
- res = appendString(res, "`", &maxLength);
- res = appendString(res, s2, &maxLength);
- res = appendString(res, "'", &maxLength);
- pfree(s2);
- res = appendString(res, ")", &maxLength); /* end of one stub */
- }
- res = appendString(res, ")", &maxLength);
-
- return(res);
- }
-
- /*--------------------------------------------------------------------
- *
- * prs2StringToStub
- *
- * GIven a "string" representation of a stub, recreate the stub.
- *--------------------------------------------------------------------
- */
- Prs2Stub
- prs2StringToStub(s)
- char *s;
- {
- int i,j,k;
- int numOfStubs;
- Prs2Stub stubs;
- Prs2OneStub oneStub;
- ObjectId ruleId;
- Prs2StubId stubId;
- int count;
- int nQuals;
- Datum constDatum;
- AttributeNumber attrNo;
- int indx;
- long l;
- char c;
- RuleLock lock;
- Size size;
- char *data;
-
-
- /*
- * Create an initially empty rule stub.
- */
- stubs = prs2MakeStub();
-
- /*
- * Now read the number of stubs;
- */
- indx = 0;
- skipToken("(", s, &indx);
- skipToken("numOfStubs:", s, &indx);
- l = readLongInt(s, &indx);
- numOfStubs = (int) l;
-
- for (i=0; i<numOfStubs; i++) {
- /*
- * read one `Prs2OneStub'
- * First read the ruleId, stubId, counter, numQuals
- */
- oneStub = prs2MakeOneStub(); /* allocate space */
- skipToken("(", s, &indx);
- skipToken("ruleId:", s, &indx);
- l = readLongInt(s, &indx);
- oneStub->ruleId = (ObjectId) l;
- skipToken("stubId:", s, &indx);
- l = readLongInt(s, &indx);
- oneStub->stubId = (Prs2StubId) l;
- skipToken("count:", s, &indx);
- l = readLongInt(s, &indx);
- oneStub->counter = (int) l;
- /*
- * now read the lock
- * (remember: it was enclosed in quotes).
- */
- skipToken("lock:", s, &indx);
- skipToken("`", s, &indx);
- oneStub->lock = StringToRuleLock(&s[indx]);
- while (s[indx++] != '\'');
- /*
- * now read the qualification
- * (remember: it was enclosed in quotes).
- */
- skipToken("qual:", s, &indx);
- skipToken("`", s, &indx);
- oneStub->qualification = StringToPlan(&s[indx]);
- while (s[indx++] != '\'');
-
- skipToken(")", s, &indx); /* end of one stub */
-
- prs2AddOneStub(stubs, oneStub);
-
- }
-
- skipToken(")", s, &indx);
- return(stubs);
- }
-
- /*====================================================================
- * MORE UTILITY ROUTINES LOCAL TO THIS FILE
- *====================================================================
- */
-
- /*--------------------------------------------------------------------
- *
- * appendString
- *
- * append string 's' to the string 'res'. *maxLengthP is the
- * memory size allocated for 'res'. If this is not enough to hold
- * both the old contents of 'res' and the appended string 's',
- * allocate some more memory.
- * It returns the result of the string concatenation, and
- * if more space has been allocated, *maxLengthP is updated.
- *
- * NOTE: this routine works even if 'res' is NULL.
- */
- static char*
- appendString(res, s, maxLengthP)
- char *res;
- char *s;
- int *maxLengthP;
- {
- char *temp;
-
- /*
- * if res is NULL, allocate some initial space
- */
-
- if (res == NULL) {
- *maxLengthP = 100;
- res = (char *) palloc(*maxLengthP);
- if (res==NULL) {
- elog(WARN, "appendString: Out of memory!");
- }
- res[0] = '\0';
- }
-
- if (strlen(s) + strlen(res) >= *maxLengthP -1) {
- while (strlen(s) + strlen(res) >= *maxLengthP -1) {
- *maxLengthP += 100;
- }
- temp = (char *) palloc(*maxLengthP);
- if (temp==NULL) {
- elog(WARN, "appendString: Out of memory!");
- }
- strcpy(temp, res);
- pfree(res);
- res = temp;
- }
- strcat(res, s);
- return(res);
- }
-
- /*--------------------------------------------------------------------
- *
- * skipToken
- *
- * read & skip the specified token 'token' from the string that
- * starts at 's[*indx]'. '*indx' is incremented accordingly
- * If there is a mismatch, signal a syntax error.
- */
- static void
- skipToken(token, s, indx)
- char *token;
- char *s;
- int *indx;
- {
- char *t;
-
- /*
- * skip blanks
- */
- while (ISBLANK(s[*indx])) {
- (*indx)++;
- }
-
- t = token;
- while (*t != '\0') {
- if (s[*indx] != *t) {
- elog(WARN,"Syntax error while reading RuleStub, token=%s", token);
- }
- t++;
- (*indx)++;
- }
- }
-
- /*--------------------------------------------------------------------
- *
- * readLongInt
- *
- * read an (long) integer from the string that
- * starts at 's[*indx]'. '*indx' is incremented accordingly
- */
- static long
- readLongInt(s, indx)
- char *s;
- int *indx;
- {
- long res;
- int sign;
-
- /*
- * skip blanks
- */
- while (ISBLANK(s[*indx])) {
- (*indx)++;
- }
-
- /*
- * Is this a negative number ?
- */
- sign = 1;
- if (s[*indx] == '-') {
- sign = -1;
- (*indx)++;
- }
-
- /*
- * Now read the number
- */
- res = 0;
- while (s[*indx] <='9' && s[*indx] >= '0') {
- res = 10*res + s[*indx] - '0';
- (*indx)++;
- }
-
- res = sign * res;
-
- return(res);
- }
-
- /*--------------------------------------------------------------------
- *
- * readChar
- *
- * read the first non blank character from the string that
- * starts at 's[*indx]'. '*indx' is incremented accordingly
- */
- static char
- readChar(s, indx)
- char *s;
- int *indx;
- {
- char c;
-
- /*
- * skip blanks
- */
- while (ISBLANK(s[*indx])) {
- (*indx)++;
- }
-
- c = s[*indx];
- (*indx)++;
- return(c);
- }
-
- /*-----------------------------------------------------------------------
- * readName
- *
- * Read a name (i.e. a string at most 16 chars long) enclosed in quotes.
- * Returns a palloced Name.
- *
- * If the name has embedded quotes they must be escaped with a
- * backslash...
- */
- static
- Name
- readName(s, indx)
- char *s;
- int *indx;
- {
- Name res;
- int i;
- char c, c1;
-
- res = (Name) palloc(sizeof(NameData));
- if (res == NULL) {
- elog(WARN, "readString: Out of memory");
- }
-
- skipToken("\"", s, indx);
-
- i = 0;
- c1 = '\0';
- c = readChar(s, indx);
- while (c!= '"' || (c=='"' && c1 == '\\')) {
- if (i>15) {
- elog(WARN, "readString: Name too large!");
- }
- res->data[i] = c;
- i++;
- c1 = c;
- c = readChar(s, indx);
- }
-
- if(i<=15) {
- res->data[i] = '\0';
- }
-
- return(res);
- }
-
-
-
-